package btb.ui;


import de.matthiasmann.twl.Alignment;
import de.matthiasmann.twl.Button;
import de.matthiasmann.twl.EditField;
import de.matthiasmann.twl.Label;
import de.matthiasmann.twl.TextArea;
import de.matthiasmann.twl.textarea.SimpleTextAreaModel;

import btb.engine.CDisplayTask;
import btb.engine.CDisplayTask.NGuiState;
import btb.engine.CTaskMessenger;
import btb.util.CUtils;


public class CGuiLogin extends AGuiObject
{
	public String logintext;
	
	// [Note]: Originally, all of these objects had the 'final' keyword.
	private Label lblTitle;
	private Label lblUsr;
	private Label lblPass;
	private SimpleTextAreaModel txtLogonModel;
	private TextArea txtLogon;
	private EditField inputUsername;
	private EditField inputPassword;
	private Button btnLogin;
	private Button btnPlayOffline;
	private Button btnExit;
	
	private Runnable btnLoginCallback = null;
	private Runnable btnPlayOfflineCallback = null;
	private Runnable btnExitCallback = null;
	
	private String username;
	private String password;
	
	public CGuiLogin(CDisplayTask _parent)
	{
		super(_parent);
	}
	
	@Override
	public void initializeGUI(int _guiDisplayOption)
	{
		initializeDisplay(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT, "Beat the Bard Prototype", BTB_THEME_02_FILEPATH, _guiDisplayOption);
	}
	
	@Override
	protected void initializeWidgets(int _guiDisplayOption)
	{
		this.lblTitle 			= new Label();
		this.lblUsr 			= new Label();
		this.lblPass 			= new Label();
		
		this.txtLogonModel 		= new SimpleTextAreaModel();
		this.txtLogon 			= new TextArea();
		
		this.inputUsername 		= new EditField();
		this.inputPassword 		= new EditField();
		
		this.btnLogin 			= new Button();
		this.btnExit 			= new Button();
		this.btnPlayOffline 	= new Button();
	}
	
	@Override
	protected void addWidgets(int _guiDisplayOption)
	{
		this.logintext = "Welcome to Beat the Bard. Enter your account information and log in, or play offline.\n";
		
		addNewLabel(this.lblTitle, "gamelabel", "Beat the Bard");
		addNewLabel(this.lblUsr, "gamelabel", "Username: ");
		addNewLabel(this.lblPass, "gamelabel", "Password: ");
		
		addNewTextArea(this.txtLogon, "gametextarea", this.logintext, this.txtLogonModel);
		
		addNewEditField(this.inputUsername, "inputfield", "");
		addNewPasswordField(this.inputPassword, "passwordfield", "", '*');
		
		addNewButton(this.btnLogin, "submitbutton", "Login");
		addNewButton(this.btnExit, "submitbutton", "Exit");
		addNewButton(this.btnPlayOffline, "submitbutton", "Play Offline");
	}
	
	@Override
	protected void resetPage(int _guiDisplayOption)
	{
		btnLogin.setText("Login");
		btnLogin.setEnabled(true);
		btnPlayOffline.setText("Play Offline");
		btnPlayOffline.setEnabled(true);
		
		inputUsername.setText("");
		inputPassword.setText("");
		
		txtLogonModel.setText(this.logintext);
	}
	
	@Override
	protected void setLayout(int _guiDisplayOption)
	{			
		// [Title bar]
		resizeWidgetRelativeToWindow(this.lblTitle, 6f / 10, 3f / 32, true);
		centerWidgetX(this.lblTitle, 2f / 32, true);
		this.lblTitle.setAlignment( Alignment.CENTER );
		
		// [Text box displaying status of connection and login operations]
		resizeWidgetRelativeToWindow(this.txtLogon, 8f / 10, 10f / 32, false);
		centerWidgetX(this.txtLogon, 6f / 32, true);
		
		// [Username and Password labels]
		resizeWidgetRelativeToWindow(this.lblUsr, 2f / 10, 3f / 32, true);
		copyWidgetSize(this.lblUsr, this.lblPass);
		placeWidgetInTightRow(this.lblUsr, null, 1, this.lblUsr.getWidth() + this.inputUsername.getWidth(), 1f / 8, 18f / 32, true);
		placeWidgetInTightRow(this.lblPass, null, 1, this.lblPass.getWidth() + this.inputPassword.getWidth(), 1f / 8, 22f / 32, true);
		
		// [Username and Password Edit Fields]
		resizeWidgetRelativeToWindow(this.inputUsername, 6f / 10, 3f / 32, true);
		copyWidgetSize(this.inputUsername, this.inputPassword);
		placeWidgetOnRightOf(this.inputUsername, this.lblUsr, -1);
		placeWidgetOnRightOf(this.inputPassword, this.lblPass, -1);
		
		// [Buttons]
		resizeWidgetRelativeToWindow(this.btnLogin, 8f / 30, 3f / 32, true);
		copyWidgetSize(this.btnLogin, this.btnPlayOffline);
		copyWidgetSize(this.btnLogin, this.btnExit);
		placeWidgetInEqualRow(this.btnLogin, 1, 3, 27f / 32, true);
		placeWidgetInEqualRow(this.btnPlayOffline, 2, 3, 27f / 32, true);
		placeWidgetInEqualRow(this.btnExit, 3, 3, 27f / 32, true);
	}
	
	@Override
	protected void removeCallBacks(int _guiDisplayOption)
	{
		if(btnLoginCallback != null)
			this.btnLogin.removeCallback(btnLoginCallback);
		if(btnPlayOfflineCallback != null)
			this.btnPlayOffline.removeCallback(btnPlayOfflineCallback);
		if(btnExitCallback != null)
			this.btnExit.removeCallback(btnExitCallback);
	}
	
	@Override
	protected void addCallBacks(int _guiDisplayOption)
	{
		btnLoginCallback = new Runnable()
		{	
			public void run()
			{
				username = CUtils.removeNonAlphanumericChars(inputUsername.getText());
				password = CUtils.removeNonAlphanumericChars(inputPassword.getText());
				
				// [TESTING CODE]: Probably get rid of this at some point.
				
				if(callingTask.ALLOW_FORCED_GUI_SWITCH && password.equals("bardsbeaten"))
				{
					if(username.equals("hub"))
						callingTask.switchGuiState(NGuiState.HUB_PAGE);
					else if(username.equals("guest"))
						callingTask.switchGuiState(NGuiState.LOBBY_PAGE_GUEST);
					else if(username.equals("host"))
						callingTask.switchGuiState(NGuiState.LOBBY_PAGE_HOST);
				}
				
				// [TESTING CODE ENDS HERE]
				
				if(username.equals("") || password.equals(""))
				{
					logintext += "Either your username or password are blank or were made up entirely of invalid characters.\n";
					updateTextWidget((SimpleTextAreaModel) txtLogon.getModel(), logintext);
				}
				else
				{
					btnLogin.setText( "Logging in..." );
					btnLogin.setEnabled( false );
					btnPlayOffline.setEnabled( false );
					
					logintext += "Attempting to establish connection...\n";
					updateTextWidget((SimpleTextAreaModel) txtLogon.getModel(), logintext);
					callingTask.setGuiRequest(CDisplayTask.GUI_CONNECTION_REQUEST);
				}
			}
		};
		
		btnPlayOfflineCallback = new Runnable()
		{
			public void run()
			{
				btnPlayOffline.setText( "Searching..." );
				btnLogin.setEnabled( false );
				btnPlayOffline.setEnabled( false );
				
				String ioEventStr = "playoffline%";
				CIOEvent playOfflineEvent = new CIOEvent(this, CIOEvent.CIOE_GUI_EVENT, ioEventStr);
				CTaskMessenger mbox = callingTask.getMailbox();
				mbox.push(CTaskMessenger.TASK_INPUT, playOfflineEvent);
				
				logintext += "Searching for other players on the network...\n";
				updateTextWidget((SimpleTextAreaModel) txtLogon.getModel(), logintext);
			}
		};
		
		btnExitCallback = new Runnable()
		{
			public void run()
			{
				logintext += "Goodbye.\n";
				updateTextWidget((SimpleTextAreaModel) txtLogon.getModel(), logintext);
				
				System.out.println(callingTask.getParentTask().getClass().getName());
				callingTask.getParentTask().kill();
			}
		};
		
		this.btnLogin.addCallback(btnLoginCallback);
		this.btnPlayOffline.addCallback(btnPlayOfflineCallback);
		this.btnExit.addCallback(btnExitCallback);
	}
	
	public void informConnectionFailure()
	{
		resetPage(DISPLAY_OPT_NONE);
		logintext += "Unable to establish connection with server. Please try again later.\n";
		updateTextWidget((SimpleTextAreaModel) txtLogon.getModel(), logintext);
		if(callingTask.getGuiRequest() == CDisplayTask.GUI_CONNECTION_REQUEST)
			callingTask.setGuiRequest(CDisplayTask.NO_GUI_REQUEST);
	}
	
	public void guiAttemptLogin(CTaskMessenger _mailbox)
	{
		String ioEventStr = "login%" + username + "%" + password + "%";
		CIOEvent loginEvent = new CIOEvent(this, CIOEvent.CIOE_GUI_EVENT, ioEventStr);
		//CTaskMessenger mbox = callingTask.getMailbox();
		_mailbox.push(CTaskMessenger.TASK_INPUT, loginEvent);
		
		logintext += "Verifying account credentials...\n";
		updateTextWidget((SimpleTextAreaModel) txtLogon.getModel(), logintext);
	}
	
	public void informLoginFailure(int _loginResult)
	{
		resetPage(DISPLAY_OPT_NONE);
		if(_loginResult == 1)
		{
			logintext += "Login failed.\n";
			updateTextWidget((SimpleTextAreaModel) txtLogon.getModel(), logintext);
		}
		else
		{
			logintext += "Login failed, for a reason beyond mortal comprehension.\n";
			updateTextWidget((SimpleTextAreaModel) txtLogon.getModel(), logintext);
		}
	}
}
